package com.gdust.gkyx.acl.utils;

import com.gdust.gkyx.model.acl.Permission;

import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: PermissionHelper
 * Package: com.gdust.gkyx.acl.utils
 * Description:工具类，用于构建权限的层级结构。通过递归方式，将扁平化的权限列表转换为具有父子关系的树形结构。
 *
 * @Author syun
 * @Create 2025/1/24 10:06
 * @Version 1.0
 */
public class PermissionHelper {
    /**
     * 构建权限树的方法
     *
     * @param allList 包含所有权限节点的扁平列表
     * @return 树形结构的权限列表
     */
    public static List<Permission> buildPermission(List<Permission> allList) {
        //创建最终数据封装List集合
        List<Permission> trees = new ArrayList<>();
        //遍历所有菜单list集合，得到第一层数据，pid=0
        for (Permission permission:allList) {
            //pid=0数据，第一层数据
            if(permission.getPid()==0) {
                // 设置当前节点的层级为1（根节点）
                permission.setLevel(1);
                //调用方法，从第一层开始往下找
                trees.add(findChildren(permission,allList));
            }
        }
        return trees;
    }

    //递归往下找，找子节点
    //permission上层节点，从这里往下找
    //allList所有菜单
    /**
     * 递归方法：查找指定节点的所有子节点
     *
     * @param permission 当前节点（父节点）
     * @param allList    包含所有权限节点的扁平列表
     * @return 当前节点及其子节点树
     */
    private static Permission findChildren(Permission permission,
                                           List<Permission> allList) {
        permission.setChildren(new ArrayList<Permission>());
        //遍历allList所有菜单数据
        //判断：当前节点id = pid是否一样，封装，递归往下找
        // 遍历所有权限节点
        for (Permission it:allList) {
            // 判断条件：当前节点的ID与子节点的父ID相同 //判断当前节点id = pid是否一样
            if(permission.getId().longValue() == it.getPid().longValue()) {
                // 设置子节点的层级，层级为父节点层级+1
                int level = permission.getLevel()+1;
                it.setLevel(level);

                // 如果当前节点的子节点列表为null，则初始化
                if(permission.getChildren()==null) {
                    permission.setChildren(new ArrayList<>());
                }
                //封装下一层数据 // 将找到的子节点加入当前节点的子节点列表，同时递归查找该子节点的子节点
                permission.getChildren().add(findChildren(it,allList));
            }
        }
        return permission;
    }
}

